using System;
using System.Web;
using System.Web.SessionState;
using Sedna.Core.Controller;
using Spring.Context.Support;
using Spring.Util;

namespace Sedna.Core.Common.Objects.Navigation
{
	/// <summary>
	/// Summary description for ScopedNode.
	/// </summary>
	/// 
	[Serializable]
	internal class ScopedNode: NavigationNode
	{
		private Scope scope;
		private string key;

	    public ScopedNode(Scope scope, string nodeExpression, Type nodeType) : base(null, nodeExpression, nodeType)
		{
			this.scope=scope;
//			this.key=StringUtils.StripFirstAndLastCharacter(nodeExpression);
			this.key=nodeExpression;
		}

		protected override object GetValueRecursive(bool autoCreate)
		{

			return GetScopedValue(key, scope);
		}

		protected override void SetValue(object newValue)
		{
			SetScopedValue(key, newValue, scope);
		}

	    public static object GetScopedValue(String key, Scope scope)
		{
			if (Scope.Request == scope)
			{
				return HttpContext.Current.Request[key];
			}
			else if (Scope.IoCContainer == scope)
			{
				return SpringContextFactory.GetContext().GetObject(key);
			}
			else if (Scope.Session == scope)
			{
				return HttpContext.Current.Session[key];
			}
			else if (Scope.Application == scope)
			{
				return HttpContext.Current.Application[key];
			}
			else if (Scope.Cookie == scope)
			{
				return HttpContext.Current.Request.Cookies[key];				
			}
			else if (Scope.ExecutionContext == scope || Scope.EC == scope)
			{
				return ExecutionContext.Current[key];
			}
			else if (Scope.Workflow == scope)
			{
				return WorkflowContext.Current[key];
			}
			else if (Scope.Page == scope && BasePage.Current != null)
			{
				return BasePage.Current.Attributes[key];
			}
            else if (Scope.Call == scope)
            {
                return ExecutionContext.Current.CallContext[key];
            }
		    else if (Scope.Current == scope)
		    {
                return ExecutionContext.Current.GetFromCurrentScope(key);
		    }

			throw new SednaException("Unknown scope value");
		}

		public static void SetScopedValue(String key, Object value, Scope scope)
		{
			if (Scope.Request == scope)
			{
				throw new SednaException("Cannot write in the Request scope");
			}
			else if (Scope.IoCContainer == scope)
			{
				throw new SednaException("Cannot write in the IoCContainer scope");
			}
			else if (Scope.Session == scope)
			{
				HttpContext.Current.Session[key] = value;
                return;
			}
			else if (Scope.Application == scope)
			{
				HttpContext.Current.Application[key] = value;
                return;
			}
			else if (Scope.Cookie == scope)
			{
				if (value is HttpCookie)
				{
					((HttpCookie)value).Name = key;
					HttpContext.Current.Response.Cookies.Add((HttpCookie)value);
				}
				else
				{
					throw new SednaException("Cannot write in the Cookie scope");
				}
                return;
			}
			else if (Scope.ExecutionContext == scope || Scope.EC == scope)
			{
				ExecutionContext.Current[key] = value;
                return;
			}
			else if (Scope.Workflow == scope)
			{
				WorkflowContext.Current[key] = value;
                return;
			}
			else if (Scope.Page == scope && BasePage.Current != null)
			{
				BasePage.Current.Attributes[key] = value;
                return;
			}
            else if (Scope.Call == scope)
            {
                ExecutionContext.Current.CallContext[key]=value;
                return;
            }
		    else if (Scope.Current ==scope)
		    {
		        ExecutionContext.Current.SetToCurrentScope(key, value);
                return;
		    }
            throw new SednaException("Unknown scope value");

		}


	}
}
